﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Text.RegularExpressions;
using System.ComponentModel;

namespace CSSAdriverapp
{
    /// <summary>
    /// Interaction logic for UpdateEvents.xaml
    /// </summary>
    public partial class UpdateEvents : Window
    {

        int term = new int();
        int count = new int();
        BackgroundWorker worker = new BackgroundWorker();  

        public UpdateEvents()
        {
            InitializeComponent();
        }

        private static bool IsTextAllowed(string text) // Makes sure its a number
        {
            Regex regex = new Regex("[^0-9]+"); //regex that matches disallowed text
            return !regex.IsMatch(text);
        }

        private static int getTerm(String csemester, String cyear)
        {
            DataClassesDataContext db = new DataClassesDataContext();

            IQueryable<int> whichYearL = from c in db.COMSERV_SEMESTER_YEARs
                                         where c.semester == csemester && c.year == cyear
                                         select c.semester_yearid;
            whichYearL.ToList();

            if (whichYearL.Count() != 0)
            {
                return whichYearL.First();
            }

            return 0;
        }

        private void DoWork(object sender, DoWorkEventArgs e)
        {

            //-----assign dates 
            DataClassesDataContext db = new DataClassesDataContext();
            //get  activities
            IQueryable<COMSERV_ACTIVITY> activitie = (from c in db.COMSERV_ACTIVITies
                                                      where c.semester_yearid == term
                                                      select c);
            count = activitie.Count();


            List<COMSERV_ACTIVITY> activities = activitie.ToList();
            List<COMSERV_ACTIVITY> uniqueactivities = new List<COMSERV_ACTIVITY>();

            foreach (COMSERV_ACTIVITY d in activities)
            {
                if (newEventCheck(d.activityid) == true)
                {
                    uniqueactivities.Add(d);
                }
            }

            foreach (COMSERV_ACTIVITY c in uniqueactivities)
            {

                List<DateTime> dt = new List<DateTime>();
                // Difference in days, hours, and minutes.
                TimeSpan ts = (DateTime)c.end_date - (DateTime)c.begin_date;
                // Difference in days.
                int differenceInDays = ts.Days;


                DateTime beginning = new DateTime();
                beginning = (DateTime)c.begin_date;
                List<String> days = new List<String>();

                if (c.needed == "Weekly" || c.needed == "BiWeekly")
                {
                    //do nothing
                }
                else
                {

                    addDates(beginning, c.activityid, days.Count());
                }
                worker.ReportProgress(1);
            }
        }

        private void WorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            //Hide your wait dialog
            this.Close();
        }

        private void StartWork()
        {
       
            worker.DoWork += DoWork;
            worker.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
            worker.WorkerReportsProgress = true;
            worker.RunWorkerCompleted += WorkerCompleted;
            worker.RunWorkerAsync();
        }

        void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            // The progress percentage is a property of e
            try
            {
                int m = Int32.Parse(yearLabel.Content.ToString());
                yearLabel.Content = m + 1;
            }
            catch (FormatException b)
            {
                Console.WriteLine(b.Message);
            }   
        }

        private void addDates(DateTime exactDay, int ID, int numdays)
        {
            DataClassesDataContext db = new DataClassesDataContext();


                Event eday = new Event { Date = exactDay.Date, ServiceID = ID };
                db.Events.InsertOnSubmit(eday);
                try
                {
                    db.SubmitChanges();
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    db.SubmitChanges();
                }

        }

        private void generateButton_Click(object sender, RoutedEventArgs e)
        {
            if (semesterComboBox.SelectedValue != null && yearTextBox.Text != "" && IsTextAllowed(yearTextBox.Text))
            {
                missingFieldsWarningLabel.Visibility = System.Windows.Visibility.Hidden;
                term = getTerm((string)semesterComboBox.SelectionBoxItem, yearTextBox.Text); //gets id of selected term
                if (term == 0)
                {
                    termDoesNotExistLabel.Visibility = System.Windows.Visibility.Visible;
                }
                else
                {
                    termDoesNotExistLabel.Visibility = System.Windows.Visibility.Hidden;

                    //Message box code
                    string message = "Are you sure? Do not close window while process is running.";
                    string caption = "Confirmation";
                    MessageBoxResult result = MessageBox.Show(message, caption,
                                             MessageBoxButton.YesNo,
                                             MessageBoxImage.Question);
                    if (result == MessageBoxResult.Yes)
                    {
                        generateButton.Visibility = System.Windows.Visibility.Hidden;
                        statusLabel.Visibility = System.Windows.Visibility.Visible;

                        try
                        {
                            StartWork();//Start doing the long update
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ex);
                        }
                    }

                }
            }
            else
            {
                missingFieldsWarningLabel.Visibility = System.Windows.Visibility.Visible;
                termDoesNotExistLabel.Visibility = System.Windows.Visibility.Hidden;
            }
        }

        private static Boolean newEventCheck(int activityid)
        {
            DataClassesDataContext db = new DataClassesDataContext();
            IQueryable<Event> events = from c in db.Events select c;
            List<int> unique = events.Select(v => v.ServiceID).Distinct().ToList(); //gets unique service IDS

            foreach (int i in unique)
            {
                if (activityid.Equals(i))
                {
                    return false;
                }
            }
            
            return true;
        }

        private void updateNotes()
        {
            DataClassesDataContext db = new DataClassesDataContext();
            IQueryable<Event> events = from c in db.Events select c;
            IQueryable<COMSERV_DATE_EXCLUDED> excluded = from c in db.COMSERV_DATE_EXCLUDEDs select c;

            List <Event> eventslist = events.ToList();
            List<COMSERV_DATE_EXCLUDED> excludedlist = excluded.ToList();
            foreach (Event c in eventslist)
            {
                COMSERV_DATE_EXCLUDED excluding = (from e in excludedlist where e.activityid == c.ServiceID && e.date == c.Date select e).FirstOrDefault();

                if (excluding == null && c.Notes == null)
                {

                }
                else if (!(c.Notes == excluding.comments))
                {
                    assignExcluded(c, excluding.comments);
                }
            }
        }

        private void assignExcluded(Event e, String comment)
        {
            DataClassesDataContext db = new DataClassesDataContext();
            // Query the database for the row to be updated.
            var query =
                from ev in db.Events
                where ev.ID == e.ID
                select ev;
            // Execute the query, and change the column values
            // you want to change.
            foreach (Event ev in query)
            {
                ev.Notes = comment;
                // Insert any additional changes to column values.
            }

            // Submit the changes to the database.
            try
            {
                db.SubmitChanges();
            }
            catch (Exception w)
            {
                Console.WriteLine(w);
                // Provide for exceptions.
            }
        }
    }
}
